/*
 * Copyright 2012 Finbudget.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package finbudgetgriddemo.client.grid;

import java.util.ArrayList;
import java.util.List;

import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.ViewImpl;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;

import finbudget.client.ui.table.Field;
import finbudget.client.ui.table.Field.Type;
import finbudget.client.ui.table.Record;
import finbudgettable.client.ui.grid.CellGrid;
import finbudgettable.client.ui.grid.ChangeHandler;
import finbudgettable.client.ui.grid.GridFactory;

public class GridView extends ViewImpl implements GridPresenter.GridViewInterface, ChangeHandler {
	public final static String fieldName = "name";
	public final static String fieldWage = "wage";
	public final static String fieldAge = "age";
	public final static String fieldDate = "date";
	public final static String fieldTime = "time";
	public final static String fieldDescription = "description";

	private final Widget widget;

	public interface Binder extends UiBinder<Widget, GridView> {
	}

	@UiField SimplePanel tablePanel;
	@UiField SimplePanel pagerPanel;
	@UiField Image imgLoading;
	@UiField HTMLPanel errorPanel;
	@UiField InlineHTML errorDescription;
	@UiField HTMLPanel panelAddRecords;

	private final CellGrid grid;
	private final GridFactory gridFactory;
	private final DispatchAsync dispatcher;
	private final GridPresenter gridPresenter;

	@Inject
	public GridView(Binder binder, GridFactory gridFactory, SimplePager.Resources pagerResources, DispatchAsync dispatcher, GridPresenter gridPresenter) {
		widget = binder.createAndBindUi(this);

		this.gridFactory = gridFactory;
		this.dispatcher = dispatcher;
		this.gridPresenter = gridPresenter;

		grid = new CellGrid(this);
		tablePanel.setWidget(grid);

		SimplePager pager = new SimplePager(TextLocation.LEFT, pagerResources, false, 0, true);
		pager.setDisplay(grid);
		pagerPanel.add(pager);

		createFields();
		requestData(50);
	}

	@Override
	public Widget asWidget() {
		return widget;
	}

	private void hideAll() {
		tablePanel.setVisible(false);
		pagerPanel.setVisible(false);
		imgLoading.setVisible(false);
		errorPanel.setVisible(false);
		panelAddRecords.setVisible(false);
	}

	@Override
	public void handleChanges(boolean hasChanges) {
	}

	private void createFields() {
		List<Field> fields = new ArrayList<Field>();

		fields.add(Field.getField(fieldName, Type.STRING, "Name", 0, 0));
		fields.add(Field.getBigDecimalField(fieldWage, "Wage", 0, 0, null));
		fields.add(Field.getField(fieldAge, Type.LONG, "Age", 0, 0));
		fields.add(Field.getField(fieldDate, Type.DATE, "Date", 0, 0));
		fields.add(Field.getField(fieldTime, Type.DATETIME, "Date and time", 0, 0));
		fields.add(Field.getField(fieldDescription, Type.DESCRIPTIONINPLACE, "Description", 0, 0));

		gridFactory.createColumns(grid, fields);
	}

	private void requestData(int recordsQty) {
		hideAll();
		imgLoading.setVisible(true);
		dispatcher.execute(new GetDataAction(recordsQty), new AsyncCallback<GetDataResult>() {

			@Override
			public void onFailure(Throwable caught) {
				imgLoading.setVisible(false);
				errorPanel.setVisible(true);
				errorDescription.setText(caught == null ? "unknown" : caught.getMessage());
			}

			@Override
			public void onSuccess(GetDataResult result) {
				imgLoading.setVisible(false);
				tablePanel.setVisible(true);
				pagerPanel.setVisible(true);
				panelAddRecords.setVisible(true);
				List<Record> records = result == null ? new ArrayList<Record>() : result.getRecords();
				if (grid.getAllRecords().size() > 0) {
					records.addAll(grid.getAllRecords());
				}
				grid.setData(records);
			}

		});
	}

	@UiHandler("add100")
	protected void add100Clicked(ClickEvent event) {
		requestData(100);
	}

	@UiHandler("add1000")
	protected void add1000Clicked(ClickEvent event) {
		requestData(1000);
	}

	@UiHandler("add10000")
	protected void add10000Clicked(ClickEvent event) {
		requestData(10000);
	}

	@UiHandler("add100000")
	protected void add100000Clicked(ClickEvent event) {
		requestData(100000);
	}

	@Override
	public Presenter<?, ?> getMyPresenter() {
		return gridPresenter;
	}
}
